home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / GX Libraries / OffscreenLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-31  |  10.9 KB  |  372 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        OffscreenLibrary.c
  4.  
  5.     Contains:    graphics libraries - offscreen support library
  6.     
  7.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  8.     
  9.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>      1/9/95    JD        changed 'boolean' to 'Boolean'
  14.          <1>      1/9/95    JD        First checked in.
  15. */
  16.  
  17.  
  18. #include <Memory.h>
  19. #include "GraphicsLibraries.h"
  20. #include "OffscreenLibrary.h"
  21.  
  22. typedef struct viewPortBufferRecord {
  23.     gxViewPort    masterPort;
  24.     gxViewPort    slavePort;
  25.     gxShape        area;
  26.     gxShape        draw;
  27.     gxViewGroup    group;
  28.     long            deviceCount;
  29.     gxViewDevice    devices[1];
  30. } viewPortBufferRecord;
  31.  
  32. static void ClearBytes(void *block, register long length)
  33. {
  34.     register char *b = (char *) block;
  35.     
  36.     do
  37.         *b++ = 0;
  38.     while (--length);
  39. }
  40.  
  41. /*
  42.     Given a gxBitmap gxShape, this routine fills out the offscreen structure with the objects necessary to draw into
  43.     the offscreen and transfer the offscreen onscreen.  See the header file for details about the offscreen structure.
  44. */
  45. void CreateOffscreen(register offscreen *os, gxShape bitShape)
  46. {
  47.     NilParamReturn(os);
  48.     ClearBytes(os, sizeof(offscreen));
  49.     NilShapeReturn(bitShape);
  50.     os->group = GXNewViewGroup();
  51.     os->device = GXNewViewDevice(os->group, bitShape);
  52.     os->port = GXNewViewPort(os->group);
  53.     os->draw = GXGetViewDeviceBitmap(os->device);        /* draw this gxShape to copy the offscreen to the screen */
  54.     os->xform = GXNewTransform();                /* assign this to shapes and they will draw offscreen */
  55.     GXSetTransformViewPorts(os->xform, 1, &os->port);
  56. }
  57.  
  58.  
  59. /*
  60.     When you're done with the offscreen, call this routine.
  61. */
  62. void DisposeOffscreen(offscreen *os)
  63. {
  64.     NilParamReturn(os);
  65.     GXDisposeShape(os->draw);        /* dispense with gxBitmap gxShape */
  66.     GXDisposeTransform(os->xform);    /* …and gxTransform */
  67.     GXDisposeViewGroup(os->group);    /* …and gxViewGroup (which disposes gxViewPort and gxViewDevice) */
  68. }
  69.  
  70.  
  71. void CopyToBitmaps(gxShape dest, gxShape source)
  72. {
  73.     offscreen destOff;
  74.     
  75.     NilShapeReturn(dest);
  76.     NilShapeReturn(source);
  77.     CreateOffscreen(&destOff, dest);
  78.     {    long portCount = GXGetShapeViewPorts(source, nil);
  79.         gxViewPort *savedPorts = (gxViewPort *) NewPtr(sizeof(gxViewPort) * portCount);
  80.         
  81.         GXGetShapeViewPorts(source, savedPorts);
  82.         GXSetShapeViewPorts(source, 1, &destOff.port);
  83.         GXDrawShape(source);
  84.         GXSetShapeViewPorts(source, portCount, savedPorts);
  85.         DisposePtr((Ptr) savedPorts);
  86.     }
  87.     DisposeOffscreen(&destOff);
  88. }
  89.  
  90. typedef struct {
  91.     gxBitmap    bits;
  92.     gxPoint        offset;
  93. } areaCharacteristics;
  94.  
  95. static areaCharacteristics GetAreaCharacteristics(gxShape area, gxViewDevice device, gxViewPort port)
  96. {
  97.     areaCharacteristics x;
  98.     gxRectangle bounds;
  99.     gxShape bitShape;
  100.     gxMapping map;
  101.  
  102.     ClearBytes(&x, sizeof(x));
  103.     ClearBytes(&bounds, sizeof(bounds));
  104.     ClearBytes(&map, sizeof(map));
  105.     bitShape = GXGetViewDeviceBitmap(device);
  106.     GXGetShapeGlobalBounds(area, port, nil, &bounds);
  107.     GXGetBitmap(bitShape, &x.bits, nil);
  108.     if (x.bits.space == gxIndexedSpace)
  109.         GXCloneColorSet(x.bits.set);
  110.     if (x.bits.profile)
  111.         GXCloneColorProfile(x.bits.profile);
  112.     GXDisposeShape(bitShape);
  113.     x.offset.x = bounds.left;
  114.     x.offset.y = bounds.top;
  115.     x.bits.width = FixedRound(bounds.right) - FixedRound(bounds.left);
  116.     x.bits.height = FixedRound(bounds.bottom) - FixedRound(bounds.top);
  117.     InvertMapping(&map, GXGetViewPortGlobalMapping(port, &map));
  118.     MapPoints(&map, 1, &x.offset);
  119.     return x;
  120. }
  121.  
  122. static void DisposeAreaCharacteristics(areaCharacteristics *x)
  123. {
  124.     if (x->bits.space == gxIndexedSpace)
  125.         GXDisposeColorSet(x->bits.set);
  126.     if (x->bits.profile)
  127.         GXDisposeColorProfile(x->bits.profile);
  128. }
  129.  
  130. static gxViewDevice NewDeviceWithAreaCharacteristics(gxViewGroup group, areaCharacteristics *x)
  131. {
  132.     gxViewDevice device;
  133.     gxShape bitShape;
  134.     gxMapping map;
  135.  
  136.     NilParamReturnNil(x);
  137.     bitShape = GXNewBitmap(&x->bits, nil);
  138.     device = GXNewViewDevice(group, bitShape);
  139.     GXDisposeShape(bitShape);
  140.     ResetMapping(&map);
  141.     MoveMapping(&map, -x->offset.x, -x->offset.y);
  142.     GXSetViewDeviceMapping(device, &map);
  143.     return device;
  144. }
  145.  
  146. static areaCharacteristics GetDeviceAreaCharacteristics(gxViewDevice device)
  147. {
  148.     areaCharacteristics x;
  149.     gxShape bitShape;
  150.     gxMapping map;
  151.  
  152.     ClearBytes(&x, sizeof(x));
  153.     ClearBytes(&map, sizeof(map));
  154.     bitShape = GXGetViewDeviceBitmap(device);
  155.     GXGetBitmap(bitShape, &x.bits, nil);
  156.     if (x.bits.space == gxIndexedSpace)
  157.         GXCloneColorSet(x.bits.set);
  158.     if (x.bits.profile)
  159.         GXCloneColorProfile(x.bits.profile);
  160.     GXDisposeShape(bitShape);
  161.     GXGetViewDeviceMapping(device, &map);
  162.     x.offset.x = -map.map[2][0];
  163.     x.offset.y = -map.map[2][1];
  164.     return x;
  165. }
  166.  
  167. static void SetDeviceAreaCharacteristics(gxViewDevice device, areaCharacteristics *x)
  168. {
  169.     gxShape bitShape;
  170.     gxBitmap bits;
  171.     gxMapping map;
  172.  
  173.     NilParamReturn(x);
  174.     bits.width = 1;
  175.     bits.height = 1;
  176.     bits.pixelSize = 1;
  177.     bits.rowBytes = 0;
  178.     bits.image = nil;
  179.     bits.space = gxIndexedSpace;
  180.     bits.set = nil;
  181.     bits.profile = nil;
  182.     bitShape = GXNewBitmap(&bits, nil);
  183.     GXSetViewDeviceBitmap(device, bitShape);
  184.     GXDisposeShape(bitShape);
  185.  
  186.     bitShape = GXNewBitmap(&x->bits, nil);
  187.     GXSetViewDeviceBitmap(device, bitShape);
  188.     GXDisposeShape(bitShape);
  189.     ResetMapping(&map);
  190.     MoveMapping(&map, -x->offset.x, -x->offset.y);
  191.     GXSetViewDeviceMapping(device, &map);
  192. }
  193.  
  194. static Boolean EqualAreaCharacteristics(areaCharacteristics *x, areaCharacteristics *y)
  195. {
  196.     NilParamReturnNil(x);
  197.     NilParamReturnNil(y);
  198.     return x->bits.space == y->bits.space
  199.         && x->bits.set == y->bits.set
  200.         && x->bits.profile == y->bits.profile
  201.         && x->offset.x == y->offset.x
  202.         && x->offset.y == y->offset.y
  203.         && x->bits.width == y->bits.width
  204.         && x->bits.height == y->bits.height
  205.         && x->bits.pixelSize == y->bits.pixelSize;
  206. }
  207.  
  208. static void AddBitmapShapes(viewPortBufferRecord *buffers)
  209. {
  210.     short i;
  211.  
  212.     NilParamReturn(buffers);
  213.     for (i = 0; i < buffers->deviceCount; i++) 
  214.     {    gxViewDevice device = buffers->devices[i];
  215.         gxShape bitShape = GXGetViewDeviceBitmap(device);
  216.         gxMapping map;
  217.     
  218.         ClearBytes(&map, sizeof(map));
  219.         GXGetViewDeviceMapping(device, &map);
  220.         GXSetShapeAttributes(bitShape, GXGetShapeAttributes(bitShape) | gxMapTransformShape);
  221.         GXMoveShape(bitShape, -map.map[2][0], -map.map[2][1]);
  222.         GXSetShapeParts(buffers->draw, 0, 0, bitShape, 0);
  223.         GXDisposeShape(bitShape);
  224.     }
  225. }
  226.  
  227. viewPortBuffer NewViewPortBuffer(gxViewPort port)
  228. {
  229.     viewPortBuffer buffersHandle;
  230.     viewPortBufferRecord *buffers;
  231.     gxTransform xform;
  232.     gxShape area;
  233.     long deviceCount;
  234.     short i;
  235.  
  236.     NilParamReturnNil(port);
  237.     area = GXNewShape(gxFullType);
  238.     xform = GXNewTransform();
  239.     GXSetTransformViewPorts(xform, 1, &port);
  240.     GXSetShapeTransform(area, xform);
  241.     GXDisposeTransform(xform);
  242.     deviceCount = GXGetShapeGlobalViewDevices(area, port, nil);
  243.     buffersHandle = (viewPortBuffer) NewHandle(sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  244.     NilParamReturnNil(buffersHandle);
  245.     HLock((Handle) buffersHandle);
  246.     buffers = *buffersHandle;
  247.     buffers->group = GXNewViewGroup();
  248.     buffers->masterPort = port;
  249.     buffers->slavePort = GXNewViewPort(buffers->group);
  250.     buffers->area = area;
  251.     buffers->draw = GXNewShape(gxPictureType);
  252.     buffers->deviceCount = deviceCount;
  253.     GXSetViewPortDither(buffers->slavePort, GXGetViewPortDither(port));
  254.     GXGetShapeGlobalViewDevices(area, port, buffers->devices);
  255.     for (i = 0; i < deviceCount; i++) 
  256.     {    gxViewDevice device = buffers->devices[i];
  257.         areaCharacteristics x = GetAreaCharacteristics(area, device, port);
  258.     
  259.         buffers->devices[i] = NewDeviceWithAreaCharacteristics(buffers->group, &x);
  260.         DisposeAreaCharacteristics(&x);
  261.     }
  262.     AddBitmapShapes(buffers);
  263.     HUnlock((Handle) buffersHandle);
  264.     return buffersHandle;
  265. }
  266.  
  267. void DisposeViewPortBuffer(viewPortBuffer buffersHandle)
  268. {
  269.     NilParamReturn(buffersHandle);
  270.     GXDisposeShape((*buffersHandle)->area);
  271.     GXDisposeShape((*buffersHandle)->draw);
  272.     GXDisposeViewGroup((*buffersHandle)->group);
  273.     DisposeHandle((Handle) buffersHandle);
  274. }
  275.  
  276. Boolean ValidViewPortBuffer(viewPortBuffer buffersHandle)
  277. {
  278.     long deviceCount;
  279.     gxViewDevice *devices;
  280.     Boolean valid = true;
  281.     short i;
  282.  
  283.     NilParamReturnNil(buffersHandle);
  284.     deviceCount = GXGetShapeGlobalViewDevices((*buffersHandle)->area, (*buffersHandle)->masterPort, nil);
  285.     if (deviceCount != (*buffersHandle)->deviceCount)
  286.         return false;
  287.     devices = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice));
  288.     NilParamReturnNil(devices);
  289.     for (i = 0; i < deviceCount; i++) 
  290.     {    areaCharacteristics x = GetAreaCharacteristics((*buffersHandle)->area, devices[i], (*buffersHandle)->masterPort);
  291.         areaCharacteristics y = GetDeviceAreaCharacteristics((*buffersHandle)->devices[i]);
  292.     
  293.         valid = EqualAreaCharacteristics(&x, &y);
  294.         DisposeAreaCharacteristics(&x);
  295.         DisposeAreaCharacteristics(&y);
  296.         if (!valid) break;
  297.     }
  298.     DisposePtr((Ptr) devices);
  299.     return valid;
  300. }
  301.  
  302. Boolean UpdateViewPortBuffer(viewPortBuffer buffersHandle)
  303. {
  304.     viewPortBufferRecord *buffers;
  305.     short state;
  306.     long deviceCount;
  307.     gxViewDevice *devices;
  308.     Boolean valid = true;
  309.     short i;
  310.  
  311.     NilParamReturnNil(buffersHandle);
  312.     state = HGetState((Handle) buffersHandle);
  313.     HLock((Handle) buffersHandle);
  314.     buffers = *buffersHandle;
  315.     deviceCount = GXGetShapeGlobalViewDevices(buffers->area, buffers->masterPort, nil);
  316.     if (deviceCount != buffers->deviceCount) {
  317.         valid = false;
  318.         GXSetPicture(buffers->draw, 0, nil, nil, nil, nil);
  319.         if (deviceCount < buffers->deviceCount) {
  320.             for (i = deviceCount; i < buffers->deviceCount; i++)
  321.                 GXDisposeViewDevice(buffers->devices[i]);
  322.             SetHandleSize((Handle) buffersHandle, sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  323.             buffers = *buffersHandle;
  324.         } else {
  325.             HUnlock((Handle) buffersHandle);
  326.             SetHandleSize((Handle) buffersHandle, sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  327.             HLock((Handle) buffersHandle);
  328.             buffers = *buffersHandle;
  329.             for (i = buffers->deviceCount; i < deviceCount; i++)
  330.                 buffers->devices[i] = nil;
  331.         }
  332.         buffers->deviceCount = deviceCount;
  333.     }
  334.     devices = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice));
  335.     NilParamReturnNil(devices);
  336.     deviceCount = GXGetShapeGlobalViewDevices(buffers->area, buffers->masterPort, devices);
  337.     for (i = 0; i < deviceCount; i++) 
  338.     {    gxViewDevice device = buffers->devices[i];
  339.         areaCharacteristics x = GetAreaCharacteristics(buffers->area, devices[i], buffers->masterPort);
  340.     
  341.         if (device) 
  342.         {    areaCharacteristics y = GetDeviceAreaCharacteristics(device);
  343.         
  344.             if (EqualAreaCharacteristics(&x, &y) == false) {
  345.                 valid = false;
  346.                 GXSetPicture(buffers->draw, 0, nil, nil, nil, nil);
  347.                 SetDeviceAreaCharacteristics(device, &x);
  348.             }
  349.             DisposeAreaCharacteristics(&y);
  350.         } else
  351.             buffers->devices[i] = NewDeviceWithAreaCharacteristics(buffers->group, &x);
  352.         DisposeAreaCharacteristics(&x);
  353.     }
  354.     DisposePtr((Ptr) devices);
  355.     if (valid == false)
  356.         AddBitmapShapes(buffers);
  357.     HSetState((Handle) buffersHandle, state);
  358.     return valid;
  359. }
  360.  
  361. gxViewPort GetViewPortBufferViewPort(viewPortBuffer buffersHandle)
  362. {
  363.     NilParamReturnNil(buffersHandle);
  364.     return (*buffersHandle)->slavePort;
  365. }
  366.  
  367. gxShape GetViewPortBufferShape(viewPortBuffer buffersHandle)
  368. {
  369.     NilParamReturnNil(buffersHandle);
  370.     return (*buffersHandle)->draw;
  371. }
  372.